namespace WP7Contrib.Services.BingMaps.Model
{
    using System.Linq;
    using Collections;
    using Common;
    using Common.Extensions;

    public class RouteDetail : BaseModel, ICloneable<RouteDetail>
    {
        private int compassDegrees;
        private string maneuverType;
        private string mode;
        private string roadType;

        private ObservableCollection<int> endPathIndices;
        private ObservableCollection<string> names;
        private ObservableCollection<int> startPathIndices;

        public RouteDetail()
        {
            this.endPathIndices = new ObservableCollection<int>();
            this.names = new ObservableCollection<string>();
            this.startPathIndices = new ObservableCollection<int>();
        }

        public int CompassDegrees
        {
            get
            {
                return this.compassDegrees;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.compassDegrees, value, () => this.CompassDegrees);
            }
        }

        public ObservableCollection<int> EndPathIndices
        {
            get
            {
                return this.endPathIndices;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.endPathIndices, value, () => this.EndPathIndices);
            }
        }

        public string ManeuverType
        {
            get
            {
                return this.maneuverType;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.maneuverType, value, () => this.ManeuverType);
            }
        }

        public string Mode
        {
            get
            {
                return this.mode;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.mode, value, () => this.Mode);
            }
        }

        public ObservableCollection<string> Names
        {
            get
            {
                return this.names;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.names, value, () => this.Names);
            }
        }

        public string NamesAsCsv
        {
            get { return string.Join(",", this.names.ToArray()); }
        }

        public string RoadType
        {
            get
            {
                return this.roadType;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.roadType, value, () => this.RoadType);
            }
        }

        public ObservableCollection<int> StartPathIndices
        {
            get
            {
                return this.startPathIndices;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.startPathIndices, value, () => this.StartPathIndices);
            }
        }

        public bool HasEndPathIndices
        {
            get { return this.endPathIndices != null && this.endPathIndices.Count != 0; }
        }

        public bool HasNames
        {
            get { return this.names != null && this.names.Count != 0; }
        }

        public bool HasStartPathIndices
        {
            get { return this.startPathIndices != null && this.startPathIndices.Count != 0; }
        }

        public RouteDetail ShallowClone()
        {
            var detail = new RouteDetail
            {
                CompassDegrees = this.compassDegrees,
                ManeuverType = this.maneuverType,
                Mode = this.mode,
                RoadType = this.roadType,
                EndPathIndices = this.endPathIndices,
                Names = this.names,
                StartPathIndices = this.startPathIndices
            };

            return detail;
        }

        public RouteDetail DeepClone()
        {
            var detail = new RouteDetail
            {
                CompassDegrees = this.compassDegrees,
                ManeuverType = this.maneuverType,
                Mode = this.mode,
                RoadType = this.roadType,
            };

            if (this.HasEndPathIndices)
            {
                var copy = new ObservableCollection<int>();
                this.endPathIndices.ForEach(copy.Add);

                detail.EndPathIndices = copy;
            }

            if (this.HasNames)
            {
                var copy = new ObservableCollection<string>();
                this.names.ForEach(copy.Add);

                detail.Names = copy;
            }

            if (this.HasStartPathIndices)
            {
                var copy = new ObservableCollection<int>();
                this.startPathIndices.ForEach(copy.Add);

                detail.StartPathIndices = copy;
            }

            return detail;
        }
    }
}